在網路服務盛行的現在,許多公司推出了儲存、虛擬機器等等的服務,電子郵件也不例外,像是 SendGrid、AWS SES、MailGun 等等,都是非常知名的服務,但是這些服務不一定都會提供 SMTP,有些服務還提供額外的功能,所以使用這些服務往往就被綁住了,未來要更換,程式得更動不少。
django-anymail 就在試著解決這個問題,它擴充了原本 Django Mail backend 的機制,並試著在各種 ESP (Email Service Provider,電子郵件服務提供者)之間提供一致的 API。對於開發者來說,只要使用 django mail / django-anymail 的 API ,未來只要調整設定,就可以換到另外一個 ESP 去了。
專案網址:django-anymail
下面就假設我們使用了 MailGun 這個 ESP。
poetry add "django-anymail[mailgun]"
INSTALLED_APPS = [
# ...
"anymail",
# ...
]
ANYMAIL = {
# (exact settings here depend on your ESP...)
"MAILGUN_API_KEY": "<your Mailgun key>",
"MAILGUN_SENDER_DOMAIN": 'mg.example.com',
}
EMAIL_BACKEND = "anymail.backends.mailgun.EmailBackend"
DEFAULT_FROM_EMAIL = "you@example.com"
SERVER_EMAIL = "your-server@example.com"
在安裝與設定之後,程式裏面要寄信,就可以這樣寫啦~
from django.core.mail import send_mail
send_mail("It works!", "This will get sent through Mailgun",
"Anymail Sender <from@example.com>", ["to@example.com"])
那如果要寄 HTML 格式的信件,可以這樣寫
from django.core.mail import EmailMultiAlternatives
from anymail.message import attach_inline_image_file
msg = EmailMultiAlternatives(
subject="Please activate your account",
body="Click to activate your account: http://example.com/activate",
from_email="Example <admin@example.com>",
to=["New User <user1@example.com>", "account.manager@example.com"],
reply_to=["Helpdesk <support@example.com>"])
# Include an inline image in the html:
logo_cid = attach_inline_image_file(msg, "/path/to/logo.jpg")
html = """<img alt="Logo" src="cid:{logo_cid}">
<p>Please <a href="http://example.com/activate">activate</a>
your account</p>""".format(logo_cid=logo_cid)
msg.attach_alternative(html, "text/html")
# Optional Anymail extensions:
msg.metadata = {"user_id": "8675309", "experiment_variation": 1}
msg.tags = ["activation", "onboarding"]
msg.track_clicks = True
# Send it:
msg.send()
用法就是跟 Django - Sending email 裡講的一樣。
目前有支援這些 ESP
在 Supported ESPs 裡,有詳列出每個 ESP 的功能,以及 django-anymail 的支援狀況。
django-anymail 的開發者建議,在選擇 ESP 的時候,要從 ESP 的送達狀況、網路延遲、正常運行時間跟對開發者的支援這些方便去考量,這樣才是對的。
這套件在設定好就可以用了,不太需要費心。真正麻煩的,反而是去申請 ESP 跟了解 ESP 。
例如,AWS SES,得先要有網域,然後去 SES 那邊申請,依照步驟去網域服務的控制台去設定網域紀錄,設定好以後,還只有 Sandbox 可以作有限度的測試、使用。如果需要提升額度或是要可以正式寄送到外面,必須要提出申請。申請得照 AWS Management console 裡的說明去提出申請,提出申請時,AWS 會要求你回答幾個問題,這幾個問題主要是要確保 AWS 自身的立場,也就是當有人回報信件被濫用或退信時 (抱怨),該怎麼去處理。這個過程,就得經過一段時間來。
這也是無可避免的,隨著快速開發與各類專業網路服務的興起,了解該專業網路服務的功能以及其限制,也變成很重要的事情。